import { execSync } from 'child_process'
import fs from 'fs'
import path from 'path'

// 配置
const NPM_REGISTRY = 'http://192.168.111.82:8299/maven/repository/npm-release/'
const defaultVersion = '0.0.1'

// 工具函数
function ensureDir(dir) {
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true })
  }
}

function cleanDir(dir) {
  if (fs.existsSync(dir)) {
    fs.rmSync(dir, { recursive: true, force: true })
  }
}

function copyFile(src, dest) {
  try {
    fs.copyFileSync(src, dest)
    return true
  } catch (err) {
    console.error(`❌ 复制文件失败: ${src} -> ${dest}`)
    console.error(err)
    return false
  }
}

// 获取组件信息
function getComponentInfo() {
  const componentName = process.argv[2]
  if (!componentName) {
    console.error('请指定要发布的组件名称，例如：pnpm publish:component BasicTable')
    process.exit(1)
  }

  const packageJson = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8'))
  const packageName = componentName.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase()

  return { componentName, packageName, packageJson }
}

// 版本号管理
function getVersionInfo(packageName) {
  const versionDir = path.join(process.cwd(), '.versions')
  const versionFile = path.join(versionDir, `${packageName}.version`)
  ensureDir(versionDir)

  let currentVersion = defaultVersion
  let nextVersion = defaultVersion

  if (fs.existsSync(versionFile)) {
    try {
      const versionData = JSON.parse(fs.readFileSync(versionFile, 'utf-8'))
      if (typeof versionData === 'string' && /^\d+\.\d+\.\d+$/.test(versionData)) {
        currentVersion = versionData
        const [major, minor, patch] = currentVersion.split('.').map(Number)
        nextVersion = `${major}.${minor}.${patch + 1}`
      }
    } catch {
      // 如果解析失败，使用默认版本
    }
  }

  return { currentVersion, nextVersion, versionFile }
}

// 主函数
async function main() {
  const { componentName, packageName, packageJson } = getComponentInfo()
  const { currentVersion, nextVersion, versionFile } = getVersionInfo(packageName)

  console.log('📦 开始发布组件...')
  console.log(`组件: ${componentName}@${nextVersion}`)

  // 工作目录
  const componentDir = path.join(process.cwd(), 'src', 'components', componentName)
  const tempDir = path.join(process.cwd(), 'temp')
  const publishDir = path.join(process.cwd(), 'publish', packageName)
  const distDir = path.join(process.cwd(), 'dist')

  try {
    // 清理目录
    cleanDir(tempDir)
    cleanDir(publishDir)
    cleanDir(distDir)
    ensureDir(tempDir)
    ensureDir(publishDir)

    // 创建临时构建文件
    const entryContent = `import type { App } from 'vue'
import Component from '../src/components/${componentName}/index.vue'

// 导出组件本身
export const ${componentName} = Component

// 导出默认组件
export default Component

// 导出 Vue 插件
export const install = (app: App) => {
  app.component('${componentName}', Component)
}
`
    fs.writeFileSync(path.join(tempDir, 'index.ts'), entryContent)

    const viteConfig = `import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import dts from 'vite-plugin-dts'

export default defineConfig({
  plugins: [
    vue(),
    dts({
      include: ['./index.ts', '../src/components/${componentName}/**/*.vue'],
      beforeWriteFile: (filePath, content) => ({
        filePath: filePath.replace('/dist/', '/'),
        content
      })
    })
  ],
  build: {
    outDir: '../dist',
    lib: {
      entry: resolve(__dirname, 'index.ts'),
      name: '${componentName}',
      fileName: (format) => \`index.\${format === 'es' ? 'mjs' : 'js'}\`,
      formats: ['es', 'umd']
    },
    rollupOptions: {
      external: ['vue', 'element-plus'],
      output: {
        globals: {
          vue: 'Vue',
          'element-plus': 'ElementPlus'
        },
        exports: 'named'  // 确保命名导出可用
      }
    }
  },
  resolve: {
    alias: {
      '@': resolve(__dirname, '../src'),
    },
  },
})`
    fs.writeFileSync(path.join(tempDir, 'vite.config.ts'), viteConfig)

    const tempPackageJson = {
      name: packageName,
      private: true,
      version: nextVersion,
      type: 'module',
      scripts: { build: 'vite build' }
    }
    fs.writeFileSync(path.join(tempDir, 'package.json'), JSON.stringify(tempPackageJson, null, 2))

    // 构建
    console.log('🔨 构建组件...')
    execSync('vite build', {
      stdio: 'inherit',
      cwd: tempDir,
      env: { ...process.env, NODE_ENV: 'production' }
    })

    // 准备发布文件
    const componentPackageJson = {
      name: packageName,
      version: nextVersion,
      description: `${componentName} component`,
      main: './index.js',
      module: './index.mjs',
      types: './index.d.ts',
      style: './style.css',
      files: [
        'index.js',
        'index.mjs',
        'index.d.ts',
        'style.css'
      ],
      sideEffects: ['*.css'],
      keywords: ['vue3', 'component', packageName],
      author: packageJson.author,
      license: packageJson.license,
      peerDependencies: {
        'vue': '^3.4.0',
        'element-plus': '^2.5.0'
      },
      publishConfig: {
        registry: NPM_REGISTRY,
        access: 'public'
      }
    }
    fs.writeFileSync(path.join(publishDir, 'package.json'), JSON.stringify(componentPackageJson, null, 2))

    // 复制文件前清理目标目录中的所有文件
    const filesToCopy = ['index.js', 'index.mjs', 'index.d.ts', 'style.css']
    for (const file of filesToCopy) {
      const destFile = path.join(publishDir, file)
      if (fs.existsSync(destFile)) {
        fs.unlinkSync(destFile)
      }
      const srcFile = path.join(distDir, file)
      if (fs.existsSync(srcFile)) {
        copyFile(srcFile, destFile)
      }
    }

    // 复制共享组件和样式
    console.log('📝 复制依赖文件...')
    const sharedDir = path.join(process.cwd(), 'src', 'shared')
    const stylesDir = path.join(process.cwd(), 'src', 'styles')
    
    if (fs.existsSync(sharedDir)) {
      fs.cpSync(sharedDir, path.join(publishDir, 'shared'), { recursive: true })
    }
    
    if (fs.existsSync(stylesDir)) {
      fs.cpSync(stylesDir, path.join(publishDir, 'styles'), { recursive: true })
    }

    // 发布
    console.log('🚀 发布组件...')
    execSync('pnpm publish --no-git-checks', {
      stdio: 'inherit',
      cwd: publishDir,
      env: { ...process.env, npm_config_registry: NPM_REGISTRY }
    })

    // 发布成功后保存版本号
    fs.writeFileSync(versionFile, JSON.stringify(nextVersion))

    console.log(`\n✨ 发布成功！`)
    console.log(`安装命令: pnpm add ${packageName}@${nextVersion} --registry=${NPM_REGISTRY}`)

  } catch (error) {
    console.error('\n❌ 发布失败:', error.message)
    process.exit(1)
  } finally {
    cleanDir(tempDir)
    cleanDir(publishDir)
  }
}

main().catch(error => {
  console.error('❌ 发布失败:', error)
  process.exit(1)
})